/*
 * Created on 22/Abr/2004
 */
package org.cyborgas.swt;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.prefs.Preferences;

import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.ContributionItem;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;

/**
 * @author rino
 *
 * Implements a MRU (Most Recently Used) file list.
 */
public class RecentFileList {

	// array that contain the filenames
	static final String MRU_MENU_MARKER = "MRU";
	private static final String MRU_DUMMY_MENU_MARKER = "dummyMRU";
	
	private ArrayList fileList;
	
	private ArrayList actions;

//	// control menu array that exists for showing the MRU
	private MenuManager menu;

	// the Separator at the bottom
	//private IContributionItem bottomItem;
	//private int bottomItemIndex;
	
	// maximum number of files in list (number of menus is the MRUMenu array)
	private int maxFiles;
	
	// upport for listeners
	private List selectionListeners = new ArrayList();

	
	private Preferences prefs;
	private static final String PREF_NODE_NAME = "mru";
	private static final String PREF_MAX_FILES = "max files";
	private static final int PREF_MAX_FILES_DEF = 4;
	private static final String PREF_FILE = "file";
	
	
	public RecentFileList(MenuManager menu, Preferences preferences) {
		this.menu = menu;
		this.prefs = preferences.node(PREF_NODE_NAME);
		
		this.maxFiles = prefs.getInt(PREF_MAX_FILES, PREF_MAX_FILES_DEF);
		this.fileList = new ArrayList(maxFiles);
		this.actions = new ArrayList(maxFiles);
		menu.add(new GroupMarker(MRU_MENU_MARKER));
		menu.appendToGroup(MRU_MENU_MARKER, new Separator());
		menu.add(new GroupMarker(MRU_DUMMY_MENU_MARKER));

		load();
	}
	
	public void dispose() {
		save();
	}

	/**
	 * @return
	 */
	public int getMaxFiles() {
		return maxFiles;
	}
	
	public int size() {
		return fileList.size();
	}

	public URI get(int index) {
		return (URI) fileList.get(index);
	}
	
	public void addListener(Listener listener) {
		this.selectionListeners.add(listener);
	}
	public void removeListener(Listener listener) {
		this.selectionListeners.remove(listener);
	}

	public void add(URI url) {
		int oldPos = fileList.indexOf(url);
		if (oldPos != -1) {
			fileList.remove(oldPos);
		}
		fileList.add(0, url);
		if (oldPos == -1) {
			addMRUAction();
			oldPos = fileList.size() - 1;
		}
		update(0, oldPos);
	}
	
	public void remove(URI url) {
		int oldPos = fileList.indexOf(url);
		if (oldPos != -1) {
			fileList.remove(oldPos);
			removeMRUAction();
			update(oldPos, fileList.size() - 1);
		}
	}
	
	private void update(int from, int to) {
		int size = this.actions.size();
		for (int i = from; i <= to && i < size; i++) {
			MRUAction action = (MRUAction) this.actions.get(i);
			action.update();
		}
	}
	
	void itemSelected(int position) {
		// notify listeners
		Event ev = new Event();
		ev.data = fileList.get(position);
		Iterator it = this.selectionListeners.iterator();
		while (it.hasNext()) {
			Listener listener = (Listener) it.next();
			listener.handleEvent(ev);
		}
	}

	private void addMRUAction() {
		if (this.actions.size() < this.maxFiles) {
			MRUAction action = new MRUAction(this, this.actions.size());
			ContributionItem contributionItem = new ActionContributionItem(action);
			this.actions.add(action);
			this.menu.appendToGroup(MRU_MENU_MARKER, action);
		}
	}

	private void removeMRUAction() {
		if (this.fileList.size() < this.actions.size()) {
			MRUAction action = (MRUAction) this.actions.remove(this.actions.size() - 1);
			this.menu.remove(action.getId());
		}
		
	}
	
	private void load() {
		String address = "";
		for (int i = 0; i < maxFiles && address != null; i++) {
			address = prefs.get(PREF_FILE + i, null);
			if (address != null) {
				try {
					fileList.add(new URI(address));
				} catch (URISyntaxException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				addMRUAction();
			}
		}
		update(0, this.actions.size() - 1);
	}
	
	private void save() {
		prefs.putInt(PREF_MAX_FILES, maxFiles);
		Iterator it = this.fileList.iterator();
		int i = 0;
		while (it.hasNext() && i < this.maxFiles) {
			URI url = (URI) it.next();
			prefs.put(PREF_FILE + i, url.toString());
			i++;
		}				
	}


}
